package com.ruoyi.web.controller.novel;

import jakarta.servlet.http.HttpServletRequest;

import org.springframework.http.*;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.client.HttpStatusCodeException;
import org.springframework.web.client.RestTemplate;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.Collections;

/**
 * 通用请求转发（透传）控制器
 *
 * @author Gemini
 *
 * 将所有指向 /novel/** 的请求完整地转发到目标服务器。
 * 这包括 HTTP 方法、URL参数、请求头以及请求体。
 */
@RestController
@RequestMapping("/novel")
public class TransferController {

    // 定义目标服务器地址
    private static final String TARGET_SERVER = "http://127.0.0.1:8000";

    // 直接实例化 RestTemplate，避免修改主应用配置
    private final RestTemplate restTemplate = new RestTemplate();

    /**
     * 捕获 /novel/ 下的所有请求并进行转发
     *
     * @param request HttpServletRequest，用于获取原始请求的所有信息
     * @param body    请求体，使用 @RequestBody 注解，Spring 会自动读取
     * @return ResponseEntity<byte[]>，将目标服务器的响应完整地返回给客户端
     */
    @RequestMapping("/**")
    public ResponseEntity<byte[]> transferRequest(HttpServletRequest request, @RequestBody(required = false) byte[] body) {
        try {
            // 1. 构建目标服务的 URI
            // 获取原始请求的 URI (例如 /novel/api/v1/some/path)
            String requestURI = request.getRequestURI();
            // 获取查询字符串 (例如 ?name=test&page=1)
            String queryString = request.getQueryString();
            // 移除代理路径前缀 /novel，得到目标路径 (例如 /api/v1/some/path)
            String targetPath = requestURI.substring("/novel".length());
            // 拼接成最终的目标 URI
            URI targetUri = new URI(TARGET_SERVER + targetPath + (queryString != null ? "?" + queryString : ""));

            // 2. 复制所有请求头
            HttpHeaders headers = new HttpHeaders();
            Collections.list(request.getHeaderNames()).forEach(headerName -> {
                // 过滤掉一些由代理服务器自动处理、不应转发的头信息
                if (!headerName.equalsIgnoreCase(HttpHeaders.HOST) &&
                    !headerName.equalsIgnoreCase(HttpHeaders.CONNECTION) &&
                    !headerName.equalsIgnoreCase(HttpHeaders.CONTENT_LENGTH)) { // Content-Length 由 RestTemplate 根据 body 自动计算
                    headers.put(headerName, Collections.list(request.getHeaders(headerName)));
                }
            });

            // 3. 获取原始请求的 HTTP 方法 (GET, POST, PUT, etc.)
            HttpMethod method = HttpMethod.valueOf(request.getMethod());

            // 4. 创建包含请求体和请求头的 HttpEntity
            HttpEntity<byte[]> requestEntity = new HttpEntity<>(body, headers);

            // 5. 使用 RestTemplate 的 exchange 方法发送请求
            // exchange 是最通用的方法，可以指定任意 HTTP 方法，并完整接收响应
            return restTemplate.exchange(targetUri, method, requestEntity, byte[].class);

        } catch (URISyntaxException e) {
            // 如果 URI 构建失败，返回 500 内部服务器错误
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(("Invalid target URI: " + e.getMessage()).getBytes());
        } catch (HttpStatusCodeException e) {
            // 捕获下游服务返回的 HTTP 错误 (例如 4xx, 5xx)
            // 将下游服务的响应状态码、响应头和响应体原样返回给客户端，实现错误透传
            return ResponseEntity.status(e.getStatusCode()).headers(e.getResponseHeaders()).body(e.getResponseBodyAsByteArray());
        } catch (Exception e) {
            // 捕获其他所有未知异常 (例如网络连接失败)
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(("Proxy request failed: " + e.getMessage()).getBytes());
        }
    }
}